﻿namespace BlogsAPI.Abstract
{
    using Interfaces;
    using System;

    /// <summary>
    /// Класс, от которого наследуются все классы взаимодействия с поисковыми механизмами
    /// </summary>
    public abstract class BasicSearch : WebInterface, ISearchEngine
    {
        /// <summary>
        /// Максимальная возможная длина запроса
        /// </summary>
        protected int MaxQueueLenght = 4096;

        /// <summary>
        /// Разделитель для условий ИЛИ
        /// </summary>
        protected string separator_or = "";

        /// <summary>
        /// Разделитель для условий И
        /// </summary>
        protected string separator_and = "";

        /// <summary>
        /// Приставка для отрицаний
        /// </summary>
        protected string separator_not = "";

        
        /// <summary>
        /// Поиск определенных слов 
        /// </summary>
        /// <param name="text">текст для поиска</param>
        /// <param name="fromDate">дата начиная с которой искать объекты, может быть нулом, тогде по максимуму!</param>
        /// <returns>массив постов удовлетворяющих поиску</returns>
        public virtual BlogPost[] SearchFor(String text, DateTime? fromDate)
        {
            return null;
        }

        /// <summary>
        /// Поиск ресурсов 
        /// </summary>
        /// <param name="link">ссылка на сайт</param>
        /// <param name="fromDate">дата начиная с которой искать объекты, может быть нулом, тогде по максимуму!</param>
        /// <returns>массив постов удовлетворяющих поиску</returns>
        /// <remarks>По умолчанию делается простой поиск с указанием этого сайта в качестве параметра</remarks>
        public virtual BlogPost[] SearchFor(Uri link, DateTime? fromDate)
        {
            return SearchFor(Common.DelHttp(link.OriginalString),fromDate);
        }

        /// <summary>
        /// Получение сложно-параметрического запроса
        /// Типа, Любое из First и Любое из Second, но не Except
        /// </summary>
        /// <param name="First">Слова для поиска</param>
        /// <param name="Second">Слова для поиска 2</param>
        /// <param name="Except">Исключающие слова</param>
        /// <returns></returns>
        public virtual String FormQueryString(string[] First, string[] Second, string[] Except)
        {
            string first_line =  String.Empty;
            string second_line = String.Empty;
            string except_line = String.Empty;
            if (First != null && First.Length > 0)
            {
                first_line = "(\"" + String.Join("\""+separator_or+"\"", First) + "\")";
            }
            if (Second != null && Second.Length > 0)
            {
                second_line = "(\"" + String.Join("\""+separator_or+"\"", Second) + "\")";
            }
            if (Except!=null && Except.Length > 0)
            {
                except_line = separator_and + separator_not
                    +"\"" + String.Join("\"" + separator_and + separator_not +"\"", Except) + "\"";
            }
            string sQueue = String.Format("{0}{3}{1}{2}",
                                        first_line,
                                        second_line,
                                        except_line,
                                       !String.IsNullOrEmpty(first_line)
                                       && !String.IsNullOrEmpty(second_line)?separator_and:"");
            //проверим, что нас устроит длина запроса, если нет, то пойдем по рекурсии
            if(sQueue.Length>MaxQueueLenght)
            {
                if (Except != null && Except.Length > 0)
                {
                    Array.Resize(ref Except,Except.Length-1);
                }
                else if (Second != null && Second.Length > 0)
                {
                    Array.Resize(ref Second, Second.Length - 1);
                }
                else if (First != null && First.Length > 0)
                {
                    Array.Resize(ref First, First.Length - 1);
                }
                sQueue = FormQueryString(First, Second, Except);
            }
            return sQueue;

        }
    }
}
